/**
 * f[i][j] 表示只看前i个物体，总体积是j的情况下，总价值最大时多少
 * result =max{f[n][0~V]}
 * f[i][j]
 * 1. 不选第 i 个物品：f[i][j] = f[i-1][j]
 * 2. 选地 i 个物品：f[i][j] = f[i-1][j-v[i]] + w[i]
 * f[i][j] = max{1,2}
 * f[0][0] = 0;
 * 时间复杂度：O(NV)
*/

/*
#include <iostream>
using namespace std;
const int N = 1010;
int n,m;
int f[N][N]; // 堆里面的所有变量会被初始化为0
int v[N],w[N];

int main()
{
    cin >> n >> m;
    for(int i = 1;i <= n; ++i) cin >> v[i] >> w[i];
    for(int i = 1;i <= n; ++i)
        for(int j = 0;j <= m; ++j)
        {
            f[i][j] = f[i-1][j];
            if(j >= v[i])    
                f[i][j] = max(f[i][j],f[i-1][j-v[i]]+w[i]);
        }
    int res = 0;
    for(int i = 0;i <= m;++i) res = max(res,f[n][i]);
    cout << res << endl;
    return 0;
}
*/

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 1010;
int n,m;
int f[N]; // 堆里面的所有变量会被初始化为0
int v[N],w[N];

int main()
{
    cin >> n >> m;
    for(int i = 1;i <= n; ++i) cin >> v[i] >> w[i];

    for(int i = 1;i <= n; ++i)
        for(int j = m;j >= v[i]; --j)
            f[j] = max(f[j],f[j-v[i]]+w[i]);
    cout << f[m] << endl;
    return 0;
}

/**
 输入：
4 5
1 2
2 4
3 4
4 5
输出：
8
*/